<template>
  <div class="cesium-draw">
    <div id="cesium-drawer" />
    <canvas id="canvas-a" class="canvas" width="700" height="100"></canvas>
    <canvas id="canvas-b" class="canvas" width="700" height="100"></canvas>
    <div class="mouse-postion">{{ nowPostion.wgs84 }}</div>
  </div>
</template>

<script>
//参考：Cesium深入浅出之图层管理器 https://blog.csdn.net/fywindmoon/article/details/113747843
import { DownOutlined, EditOutlined } from '@ant-design/icons-vue';
import { defineComponent, ref, watch } from 'vue';
import * as Cesium from '@cesium/Source/Cesium.js';
import MousePosition from '@functional/utils/mousePosition';
import SysMathTool from './MathTools';
import EllipseGeometryLibraryEx from './EllipseGeometryLibraryEx_';
import PrimitivePoints from './PrimitivePoints';
import { LonlatPointsTerrainData, CartographicPointsTerrainData } from './TerrainToolCopy';
import * as turf from '@turf/turf';

export default defineComponent({
  name: 'viewRangeTerrain', // 可视域分析-地形
  components: { DownOutlined, EditOutlined },
  setup() {
    return {
      viewer: null
    };
  },
  data() {
    return {
      nowPostion: {}
    };
  },
  computed: {},
  watch: {},
  mounted() {
    this.initViewer();
  },
  beforeUnmount() {
    if (this.viewer) {
      this.viewer.destroy();
      this.viewer = null;
    }
  },
  methods: {
    onViewerInited(viewer) {
      let vm = this;
      new MousePosition(viewer, pos => {
        vm.nowPostion = pos;
      });
    },

    initViewer() {
      let vm = this;
      Cesium.Ion.defaultAccessToken = $accessToken.default;
      // let terrainProvider = new Cesium.CesiumTerrainProvider({
      //   url: '//zzgis.com/cdn/3d/data/Terrain/beijing/'
      // });
      var terrainProvider = Cesium.createWorldTerrain();
      var viewer = new Cesium.Viewer('cesium-drawer', {
        // imageryProvider: osm,
        contextOptions: {
          webgl: {
            alpha: true
          }
        },
        animation: false,
        // baseLayerPicker: false,
        fullscreenButton: false,
        vrButton: false,
        homeButton: false,
        timeline: false,
        imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
          // url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer',
          url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
        }),
        selectionIndicator: false,
        infoBox: false,
        // 注释时相当于使用默认地形，解开注释相当于使用全球地形
        terrainProvider,
        shouldAnimate: true //动画播放
      });

      //开启深度检测
      // viewer.scene.globe.depthTestAgainstTerrain = true;

      this.viewer = viewer;
      this.onViewerInited(viewer);

      this.initEffects(terrainProvider);

      this.viewer.flyTo(this.viewer.entities);
    },

    initEffects(terrainProvider) {
      const viewer = this.viewer;

      //取消双击事件
      //viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
      //设置homebutton的位置
      Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(116.15, 40.54, 116.25, 40.56); //Rectangle(west, south, east, north)
      //设置初始位置
      viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(116.2, 40.55, 30000)
      });

      //开启深度检测
      //viewer.scene.globe.depthTestAgainstTerrain = true;
      viewer.scene.fxaa = false;
      viewer.scene.fog.enabled = false;
      viewer.scene.globe.depthTestAgainstTerrain = true;

      //可视域
      var primitiveKSY = [];
      function DrawLineKSY() {
        if (primitiveKSY.length > 0) {
          return;
        }
        var viewHeight = 1.5;
        var cartographicCenter = Cesium.Cartographic.fromDegrees(116.18, 40.61);
        var cartesianCenterH0 = Cesium.Cartesian3.fromRadians(cartographicCenter.longitude, cartographicCenter.latitude);
        var cartesianPointH0 = Cesium.Cartesian3.fromDegrees(116.2, 40.62);
        var ab = Cesium.Cartesian3.distance(cartesianCenterH0, cartesianPointH0);
        var eopt = {};
        eopt.semiMinorAxis = ab;
        eopt.semiMajorAxis = ab;
        eopt.rotation = 0;
        eopt.center = cartesianCenterH0;
        eopt.granularity = Math.PI / 45.0; //间隔
        var ellipse = EllipseGeometryLibraryEx.computeEllipseEdgePositions(eopt);
        for (var i = 0; i < ellipse.outerPositions.length; i += 3) {
          //逐条计算可视域
          var cartesian = new Cesium.Cartesian3(ellipse.outerPositions[i], ellipse.outerPositions[i + 1], ellipse.outerPositions[i + 2]);
          var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
          var deltaRadian = (0.00005 * Math.PI) / 180.0; //Cesium.Math.RADIANS_PER_DEGREE
          var cartographicArr = SysMathTool.InterpolateLineCartographic(cartographicCenter, cartographic, deltaRadian);
          CartographicPointsTerrainData(terrainProvider, cartographicArr, function(terrainData) {
            if (terrainData.length > 0) {
              var preVisible = true;
              var cartesiansLine = [];
              var colors = [];
              for (var j = 1; j < terrainData.length; j++) {
                //逐点计算可见性
                var visible = true; //该点可见性
                if (j > 1) {
                  var cartographicCenterHV = new Cesium.Cartographic(terrainData[0].longitude, terrainData[0].latitude, terrainData[0].height + viewHeight);
                  //
                  if (preVisible) {
                    //
                    var curPoint = SysMathTool.InterpolateIndexLineHeightCartographic(cartographicCenterHV, terrainData[j], j, j - 1);
                    if (curPoint.height >= terrainData[j - 1].height) {
                      preVisible = true;
                      visible = true;
                    } else {
                      preVisible = false;
                      visible = false;
                    }
                  } else {
                    //插值到当前
                    var curPointArr = SysMathTool.Interpolate2IndexLineHeightCartographic(cartographicCenterHV, terrainData[j], j, j - 1);
                    for (var k = 0; k < curPointArr.length; k++) {
                      if (curPointArr[k].height >= terrainData[k].height) {
                        preVisible = true;
                        visible = true;
                      } else {
                        preVisible = false;
                        visible = false;
                        break;
                      }
                    }
                  }
                }
                var cartesianTemp = Cesium.Cartesian3.fromRadians(terrainData[j].longitude, terrainData[j].latitude, terrainData[j].height + 0.1);
                cartesiansLine.push(cartesianTemp);
                //绘制点
                if (visible) {
                  colors.push(0);
                  colors.push(0);
                  colors.push(1);
                  colors.push(1);
                } else {
                  colors.push(1);
                  colors.push(0);
                  colors.push(0);
                  colors.push(1);
                }
              }

              //绘制结果
              const primitivePoints = new PrimitivePoints(viewer, { viewer: viewer, Cartesians: cartesiansLine, Colors: colors });
              var pointsKSY = primitivePoints.create()
              primitiveKSY.push(pointsKSY);
            } else {
              alert('高程异常！');
            }
          });
        }
      }

      setTimeout(function() {
        DrawLineKSY();
      }, 5000);
    }
  }
});
</script>

<style scoped lang="less">
.cesium-draw {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  color: white;
  font-size: 14px;

  #cesium-drawer {
    width: 100%;
    height: 100%;
    overflow: hidden;
    :deep(.cesium-viewer-bottom) {
      display: none !important;
    }
  }

  .mouse-postion {
    position: absolute;
    bottom: 10px;
    right: 10px;
    font-size: 14px;
    padding: 8px 12px;
    line-height: 16px;
    color: white;
    z-index: 9999;
    background-color: rgba(40, 48, 60, 1);
    border-radius: 3px;
    opacity: 0.8;
  }
}

.chart-container {
  position: absolute;
  bottom: 7px;
  left: 7px;
  background-color: rgba(0, 0, 0, 0.5);

  #profileChart {
    width: 600px;
    height: 300px;
  }
}
#canvas-a {
  top: 10px;
  display: none;
}

#canvas-b {
  top: 120px;
  display: none;
}
</style>
